import torch
from torch import nn
from torch.nn import functional as F
import torchvision
from    torch import optim

device = torch.device('cuda:0')

batch_size = 128

# step1. load dataset
train_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data', train=True, download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data/', train=False, download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size, shuffle=False)

sample = next(iter(train_loader))

print(sample[0].shape, sample[1].shape)

def one_hot(label, depth=10):
    out = torch.zeros(label.size(0), depth)
    idx = torch.LongTensor(label).view(-1, 1)
    out.scatter_(dim=1, index=idx, value=1)
    return out

def load_checkpoint(model, checkpoint_PATH, optimizer=None):

    model_CKPT = torch.load(checkpoint_PATH)
    if optimizer == None:
        model.load_state_dict(model_CKPT['state_dict'])
        print('loading checkpoint!')
        return model
    else:
        model.load_state_dict(model_CKPT['state_dict'])
        print('loading checkpoint!')
        optimizer.load_state_dict(model_CKPT['optimizer'])
        return model, optimizer

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.layer1 = nn.Linear(784, 256)
        self.layer2 = nn.Linear(256, 128)
        self.layer3 = nn.Linear(128, 64)
        self.layer4 = nn.Linear(64, 10)

    def forward(self, input):
        x = F.relu(self.layer1(input))
        x = F.relu(self.layer2(x))
        x = F.relu(self.layer3(x))
        out = self.layer4(x)

        return out
path = 'checkpoint/all_state.pth'
model = Model().to(device)
# model.load_state_dict(torch.load('mnist_weight.pth')) 加载网络权值的方法
# model = torch.load('mnist_model.pth') 加载网络的方法
model = load_checkpoint(model, path)
model.eval()

# 打印模型的 state_dict
print("Model's state_dict:")
for param_tensor in model.state_dict():
    print(param_tensor, "\t", model.state_dict()[param_tensor].size())

totalacc = 0
for x, y in test_loader:
    x = x.view(x.shape[0], 28 * 28)
    x = x.to(device)
    y = y.to(device)
    out = model(x)
    pred = out.argmax(dim=1)
    sumauccary = pred.eq(y).sum().float().item()
    totalacc += sumauccary

total_num = len(test_loader.dataset)
acc = totalacc / total_num
print('acc:', acc)